#ifndef __ENP_CLIENTFACTORY_H__
#define __ENP_CLIENTFACTORY_H__

#include "enpdef.h"
#include "enpclient.h"

enum
{
    LIST_COUNT = 2,
    INDEX_COUNT = 2,

    // 第一条索引表示是否分配
    ALLOC_INDEX = 0,
    FREE_LIST = 0,
    USED_LIST = 1,

    // 第二条索引表示是否有残留数据
    REMAIN_INDEX = 1,
    EMPTY_LIST = 0,
    REMAIN_LIST = 1,
};

class CEnpClientFactory
{
protected:
    CTLib::CTObjectMgr<CEnpClient>       m_stMgr;
	unsigned int 				     	m_uiClientSeq;			///< 客户端序号，每个客户端连接分配一个

public:
    CEnpClientFactory();
    virtual ~CEnpClientFactory();

    int Init(const char* pszBuffer, size_t iBufferSize, int iObjectCount);

    static size_t CountSize(int iObjectCount);

    /**
    * 根据下标返回EnpClient对象
    * @return 参数非法时返回NULL
    */
    CEnpClient* CalcObject(int iIndex);

    /**
    * pstClient在数组中的下标
    */
    int CalcObjectPos(const CEnpClient* pstClient) const;

    CEnpClient* Alloc();
    int Free(CEnpClient* pstClient);

    int Head(int iListID, int iIndexID)
    {
        return m_stMgr.Head(iListID, iIndexID);
    }

    int Next(int i, int iIndexID)
    {
        return m_stMgr.Next(i, iIndexID);
    }

    int Size(int iListID, int iIndexID)
    {
        return m_stMgr.Size(iListID, iIndexID);
    }

    int GetObjectCount() const
    {
        return m_stMgr.GetObjectCount();
    }

    int SetEmpty(CEnpClient* pstClient);
    int SetRemain(CEnpClient* pstClient);
    bool IsEmpty(CEnpClient* pstClient);
	bool IsFree(CEnpClient* pstClient)
	{
		int i = CalcObjectPos(pstClient);
		return m_stMgr.Flag(i, ALLOC_INDEX) == FREE_LIST;
	}

	unsigned int GetClientSeq()
	{
		return ++m_uiClientSeq;
	}
};

#endif //__ENP_CLIENTFACTORY_H__
